package com.sojson.util.encrypt.bothway.imparity.bean;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;

import com.sojson.base.impl.BaseUtilDto;
import com.sojson.util.encrypt.bothway.alike.base64.Base64Util;
import com.sojson.util.encrypt.bothway.imparity.rsa.RsaUtil;

/**
 * 自定义非对称加解密Bean
 * 
 * @author liu
 * @date 2020-09-12
 */
public class CustomKeyPair extends BaseUtilDto {

    /***/
    private static final long serialVersionUID = 305652430410636313L;

    /** 公钥 */
    private PublicKey publicKey;
    /** 私钥 */
    private PrivateKey privateKey;
    /** 公钥 */
    private String publicKeyStr;
    /** 私钥 */
    private String privateKeyStr;
    /** 公钥 */
    private byte[] publicKeyByte;
    /** 私钥 */
    private byte[] privateKeyByte;

    public CustomKeyPair() {}

    public CustomKeyPair(PublicKey publicKey, PrivateKey privateKey) throws Exception {
        setPublicKey(publicKey);
        setPrivateKey(privateKey);
        objToByte(publicKey, privateKey);
        byteToStr(getPublicKeyByte(), getPrivateKeyByte());
    }

    public CustomKeyPair(String publicKey, String privateKey) throws Exception {
        setPublicKeyStr(publicKey);
        setPrivateKeyStr(privateKey);
        setPublicKey(RsaUtil.loadPublicKey(publicKey));
        setPrivateKey(RsaUtil.loadPrivateKey(privateKey));
    }

    public CustomKeyPair(byte[] publicKey, byte[] privateKey) throws Exception {
        setPublicKeyByte(publicKey);
        setPrivateKeyByte(privateKey);
        init();
    }

    /** 获取 公钥 */
    public PublicKey getPublicKey() {
        return publicKey;
    }

    /** 设置 公钥  */
    public void setPublicKey(PublicKey publicKey) {
        this.publicKey = publicKey;
    }

    /** 获取 私钥 */
    public PrivateKey getPrivateKey() {
        return privateKey;
    }

    /** 设置 私钥  */
    public void setPrivateKey(PrivateKey privateKey) {
        this.privateKey = privateKey;
    }

    /** 获取 公钥 */
    public String getPublicKeyStr() {
        return publicKeyStr;
    }

    /** 设置 公钥  */
    public void setPublicKeyStr(String publicKeyStr) {
        this.publicKeyStr = publicKeyStr;
    }

    /** 获取 私钥 */
    public String getPrivateKeyStr() {
        return privateKeyStr;
    }

    /** 设置 私钥  */
    public void setPrivateKeyStr(String privateKeyStr) {
        this.privateKeyStr = privateKeyStr;
    }

    /** 获取 公钥 */
    protected byte[] getPublicKeyByte() {
        return publicKeyByte;
    }

    /** 设置 公钥  */
    protected void setPublicKeyByte(byte[] publicKeyByte) {
        this.publicKeyByte = publicKeyByte;
    }

    /** 获取 私钥 */
    protected byte[] getPrivateKeyByte() {
        return privateKeyByte;
    }

    /** 设置 私钥  */
    protected void setPrivateKeyByte(byte[] privateKeyByte) {
        this.privateKeyByte = privateKeyByte;
    }

    private void objToByte(PublicKey publicKey, PrivateKey privateKey) throws Exception {
        setPublicKeyByte(publicKey.getEncoded());
        setPrivateKeyByte(privateKey.getEncoded());
    }

    private void init() throws Exception {
        byte[] publicKeyByte = getPublicKeyByte();
        byte[] privateKeyByte = getPrivateKeyByte();

        byteToObj(publicKeyByte, privateKeyByte);
        byteToStr(publicKeyByte, privateKeyByte);
    }

    protected void byteToObj(byte[] publicKey, byte[] privateKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(RsaUtil.KEY_ALGORITHM);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKey);
        setPublicKey(keyFactory.generatePublic(x509KeySpec));
        KeyFactory keyFactory2 = KeyFactory.getInstance(RsaUtil.KEY_ALGORITHM);
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(privateKey);
        setPrivateKey(keyFactory2.generatePrivate(x509EncodedKeySpec));
    }

    protected void byteToStr(byte[] publicKey, byte[] privateKey) throws Exception {
        setPublicKeyStr(encryptContentToStr(publicKey));
        setPrivateKeyStr(encryptContentToStr(privateKey));
    }

    /**
     * 加密
     * 
     * @param data      内容
     * @param publicKey 公钥
     * @return
     * @throws Exception 
     */
    protected String encryptContentToStr(byte[] data) {
        return Base64Util.encryptToStr(data);
    }

    /**
     * 解密
     * 
     * @param data          内容
     * @param privateKey    私钥
     * @return
     * @throws Exception 
     */
    protected byte[] decryptContentToByte(String data) {
        return Base64Util.decryptToByte(data);
    }

}